package main.test.SparkAPI.Baics.funcs

/**
 * Identify the components of a function
 * Implement functions in scala
 * Define func parameters with defaults
 * When coding, functions are the most fundamental block of code.
 * They provide instructions on how to perfom a given task;
 * without them, youll not be able to define how your
 * application works.
 * Scala treats functions as its first class
 * citizens:
 * they are an essential component of your program with
 * different uses and shape.
 * For example, you can use partial functions , anonymous functions, higher
 * order functions, and more! In this lesson youll
 * review the basics of functions in scala and analyze their different components.
 * you'll also see how to define a function.
 * In the capstone for this unit, you'll
 * use functions to provide instructions on how
 * to operate your vending machine.
 */

/**
 * Consider this
 * You can have many different types of functions in scalaL
 * abstract concrete, annoymous,higher order,pure,impure
 * I'll gradually introduce you to most of them later in the book.
 * Consider programming languages you have encountered so far; what kink of
 * fuctions do the offer?
 */

object testFuncs {
  //Functions

  /**
   * Suppos you wnat to determine if a given number is even
   */
  def isEven(n: Int): Boolean= n % 2 == 0

  /**
   * It implements a function called isEven, in scala,
   * a functions identifies some computation that takes zero or
   * more parameters, and that may or may not return a value.
   * in scala, a function can throw exceptions or never terminate:
   */
 def myFunc(n: Int):Boolean = {
   if (n<0) throw new RuntimeException("Error!")
   n % 2 == 0
 }

def myFunc2(n: Int): Boolean = {
  if (n < 0)  myFunc2(n)
  n % 2 == 0
}

  /**
   * For any negative number, the function myFunc throws a runtime exception.
   * The function myFunc2 never terminates as it keeps calling itself(more on this
   * when I introduce you to pure and impure functions)
   * funciton has two main parts: a signature that defines what
   * it does and an implementation that details how it does it.
   * You can split a function signature further into its name, parameters,
   * and return type:
   * Keyword Name Parameters Return type Implementation
   */
  /**
   * The keyword def and a function name:
   * when declaring a basic function,
   * use keyword def followed by a name.
   * When using the keyword def, a function must always have a name:
   * {{{
   *   def myFunc() = ??? // Placeholder for future implementation
   *
   * }}}
   * the symbol ??? is one of the most useful and practical features in
   * scala.It is a placeholder for future code: it
   * tells the compiler that its implementation is a currently missing,
   * but you will add it later. If the interpreter evaluate the symbol ???
   * at runtime, it will throw a NotImplementedError exception.
   * Scala can infer types so that you can often omit them.
   * When using the symbol ??? you should provide an explicit return type
   * even if not mandatory; the compiler doesn't have much information,
   * so it can struggle to infer the correct one.
   * Being explicit can also help remind you later on what your
   * intention was and what your implementation should return.
   * The symbol ???is a useful tool when designing how the different components
   * of your program interact.
   * It allows you to focus on your code's high-level structure rather than on implementation details.
   * Starting with overall design rather  a detailed implementation is an excellent practice to develop programs that are
   * easy to use, maintain, and understand.
   */
}

